//===-- Double-precision log(x) function ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/log.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/PolyEval.h"
#include "src/__support/FPUtil/double_double.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY

#include "common_constants.h"
#include "log_range_reduction.h"

namespace LIBC_NAMESPACE {

// 128-bit precision dyadic floating point numbers.
using Float128 = typename fputil::DyadicFloat<128>;
using MType = typename Float128::MantissaType;
using Sign = fputil::Sign;

namespace {

// A simple upper bound for the error of e_x * log(2) - log(r).
constexpr double HI_ERR = 0x1.0p-85;

// Extra errors from P is from using x^2 to reduce evaluation latency.
constexpr double P_ERR = 0x1.0p-50;

// log(2) with 128-bit prepcision generated by SageMath with:
//   sage: (s, m, e) = RealField(128)(2).log().sign_mantissa_exponent();
//   sage: print("MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})");
const Float128 LOG_2(Sign::POS, /*exponent=*/-128, /*mantissa=*/
                     MType({0xc9e3b39803f2f6af, 0xb17217f7d1cf79ab}));

alignas(64) const LogRR LOG_TABLE = {
    // -log(r) with 128-bit precision generated by SageMath with:
    //
    // for i in range(128):
    //   r = 2^-8 * ceil( 2^8 * (1 - 2^(-8)) / (1 + i*2^(-7)) );
    //   s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
    //   print("{Sign::POS,", e, ", MType({", hex(m % 2^64), ",", hex((m >> 64)
    //   % 2^64),
    //         "})},");
    /* .step_1= */ {
        {Sign::POS, 0, MType(0)},
        {Sign::POS, -134, MType({0x662d417ced007a46, 0x8080abac46f38946})},
        {Sign::POS, -133, MType({0x91d082dce3ddcd38, 0x8102b2c49ac23a4f})},
        {Sign::POS, -133, MType({0xda5f3cc0b3251dbd, 0xc24929464655f45c})},
        {Sign::POS, -132, MType({0xb9e3aea6c444ef07, 0x820aec4f3a222380})},
        {Sign::POS, -132, MType({0x521016bd904dc968, 0xa33576a16f1f4c64})},
        {Sign::POS, -132, MType({0xbe97660a23cc540d, 0xc4a550a4fd9a19a8})},
        {Sign::POS, -132, MType({0xe09f5fe2058d6006, 0xe65b9e6eed965c36})},
        {Sign::POS, -131, MType({0x1fecdfa819b96098, 0x842cc5acf1d03445})},
        {Sign::POS, -131, MType({0xa7c9859530a45153, 0x8cb9de8a32ab368a})},
        {Sign::POS, -131, MType({0x976d3b5b45f6ca0b, 0x9defad3e8f73217a})},
        {Sign::POS, -131, MType({0xe8b8b88a14ff0ce, 0xaf4ad26cbc8e5be7})},
        {Sign::POS, -131, MType({0x6a677b4c8bec22e1, 0xb8069857560707a3})},
        {Sign::POS, -131, MType({0xeaf51f66692844ba, 0xc99af2eaca4c4570})},
        {Sign::POS, -131, MType({0xa8112e35a60e6375, 0xdb56446d6ad8deff})},
        {Sign::POS, -131, MType({0x196ab34ce0bccd12, 0xe442c00de2591b47})},
        {Sign::POS, -131, MType({0x4066e87f2c0f7340, 0xf639cc185088fe5d})},
        {Sign::POS, -131, MType({0xc17bd40d8d9291ec, 0xff4489cedeab2ca6})},
        {Sign::POS, -130, MType({0x9c5a0fe396f40f1e, 0x88bc74113f23def1})},
        {Sign::POS, -130, MType({0x88713268840cbcc0, 0x8d515bf11fb94f1c})},
        {Sign::POS, -130, MType({0x65c0da506a088484, 0x968b08643409ceb6})},
        {Sign::POS, -130, MType({0x411a5b944aca8708, 0x9b2fe580ac80b17d})},
        {Sign::POS, -130, MType({0xa9fb6cf0ecb411b7, 0xa489ec199dab06f2})},
        {Sign::POS, -130, MType({0xcad2fb8d48054ae0, 0xa93f2f250dac67d1})},
        {Sign::POS, -130, MType({0x2c3c2e77904afa78, 0xb2ba75f46099cf8b})},
        {Sign::POS, -130, MType({0x34c7bc3d32750fde, 0xb780945bab55dce4})},
        {Sign::POS, -130, MType({0x9a631e830fd30904, 0xc11e0b2a8d1e0ddb})},
        {Sign::POS, -130, MType({0xaa8b6997a402bf30, 0xc5f57f59c7f46155})},
        {Sign::POS, -130, MType({0x2c507fb7a3d0bf6a, 0xcad2d6e7b80bf914})},
        {Sign::POS, -130, MType({0x5f53bd2e406e66e7, 0xd49f69e456cf1b79})},
        {Sign::POS, -130, MType({0x58a98f2ad65bee9b, 0xd98ec2bade71e539})},
        {Sign::POS, -130, MType({0x4d57da945b5d0aaa, 0xde8439c1dec56877})},
        {Sign::POS, -130, MType({0xc524848e3443e040, 0xe881bf932af3dac0})},
        {Sign::POS, -130, MType({0x11d49f96cb88317b, 0xed89ed86a44a01aa})},
        {Sign::POS, -130, MType({0x3b020fa1820c9492, 0xf29877ff38809091})},
        {Sign::POS, -130, MType({0x54d2238f75f969b1, 0xf7ad6f26e7ff2ef7})},
        {Sign::POS, -130, MType({0xca0cdf301431b60f, 0xfcc8e3659d9bcbec})},
        {Sign::POS, -129, MType({0x62dda9d2270fa1f4, 0x8389c3026ac3139b})},
        {Sign::POS, -129, MType({0x163ceae88f720f1e, 0x86216b3b0b17188b})},
        {Sign::POS, -129, MType({0x9c5a0fe396f40f1e, 0x88bc74113f23def1})},
        {Sign::POS, -129, MType({0xf7a5168126a58b9a, 0x8b5ae65d67db9acd})},
        {Sign::POS, -129, MType({0x5147bdb6ddcaf59c, 0x8dfccb1ad35ca6ed})},
        {Sign::POS, -129, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
        {Sign::POS, -129, MType({0x4a5004f3ef063313, 0x95f783e6e49a9cfa})},
        {Sign::POS, -129, MType({0x2cdec34784707839, 0x98a78f0e9ae71d85})},
        {Sign::POS, -129, MType({0xd878bbe3d392be25, 0x9b5b3bb5f088b766})},
        {Sign::POS, -129, MType({0x5b035eae273a855f, 0x9e1293b9998c1daa})},
        {Sign::POS, -129, MType({0xbb2438273918db7e, 0xa0cda11eaf46390d})},
        {Sign::POS, -129, MType({0xf698298adddd7f32, 0xa38c6e138e20d831})},
        {Sign::POS, -129, MType({0xe4f5275c2d15c21f, 0xa64f04f0b961df76})},
        {Sign::POS, -129, MType({0x8164c759686a2209, 0xa9157039c51ebe70})},
        {Sign::POS, -129, MType({0xf72ea07749ce6bd3, 0xabdfba9e468fd6f6})},
        {Sign::POS, -129, MType({0x7dd6e688ebb13b03, 0xaeadeefacaf97d35})},
        {Sign::POS, -129, MType({0x18ce51fff99479cd, 0xb1801859d56249dc})},
        {Sign::POS, -129, MType({0x2756eba00bc33978, 0xb45641f4e350a0d3})},
        {Sign::POS, -129, MType({0xbe1116c3466beb6d, 0xb730773578cb90b2})},
        {Sign::POS, -129, MType({0x49dc60b2b059a60b, 0xba0ec3b633dd8b09})},
        {Sign::POS, -129, MType({0x2efd17781bb3afec, 0xbcf13343e7d9ec7d})},
        {Sign::POS, -129, MType({0x37eda996244bccb0, 0xbfd7d1dec0a8df6f})},
        {Sign::POS, -129, MType({0x33337789d592e296, 0xc2c2abbb6e5fd56f})},
        {Sign::POS, -129, MType({0x1a18fb8f9f9ef280, 0xc5b1cd44596fa51e})},
        {Sign::POS, -129, MType({0x688ce7c1a75e341a, 0xc8a5431adfb44ca5})},
        {Sign::POS, -129, MType({0x2d7e9307c70c0668, 0xcb9d1a189ab56e76})},
        {Sign::POS, -129, MType({0xef2f3f4f861ad6a9, 0xce995f50af69d861})},
        {Sign::POS, -129, MType({0x7f9d79f51dcc7301, 0xd19a201127d3c645})},
        {Sign::POS, -129, MType({0x7f9d79f51dcc7301, 0xd19a201127d3c645})},
        {Sign::POS, -129, MType({0x5f53bd2e406e66e7, 0xd49f69e456cf1b79})},
        {Sign::POS, -129, MType({0xad88bba7d0cee8e0, 0xd7a94a92466e833a})},
        {Sign::POS, -129, MType({0x96c20cca6efe2ac5, 0xdab7d02231484a92})},
        {Sign::POS, -129, MType({0xf40a666c87842843, 0xddcb08dc0717d85b})},
        {Sign::POS, -129, MType({0x7fe8e1802aba24d6, 0xe0e30349fd1cec80})},
        {Sign::POS, -129, MType({0x7fe8e1802aba24d6, 0xe0e30349fd1cec80})},
        {Sign::POS, -129, MType({0x3eadb651b49ac53a, 0xe3ffce3a2aa64922})},
        {Sign::POS, -129, MType({0x304e1653e71d9973, 0xe72178c0323a1a0f})},
        {Sign::POS, -129, MType({0xe9a767a80d6d97e8, 0xea481236f7d35baf})},
        {Sign::POS, -129, MType({0x4f91cf4b33e42998, 0xed73aa4264b0ade9})},
        {Sign::POS, -129, MType({0xfc66eb6408ff6433, 0xf0a450d139366ca6})},
        {Sign::POS, -129, MType({0xfc66eb6408ff6433, 0xf0a450d139366ca6})},
        {Sign::POS, -129, MType({0xac8d42f78d3e65d3, 0xf3da161eed6b9aaf})},
        {Sign::POS, -129, MType({0x5a470250d40ebe90, 0xf7150ab5a09f27f4})},
        {Sign::POS, -129, MType({0xb780a545a1b54dcf, 0xfa553f7018c966f2})},
        {Sign::POS, -129, MType({0xb780a545a1b54dcf, 0xfa553f7018c966f2})},
        {Sign::POS, -129, MType({0x8f05924d258c14c5, 0xfd9ac57bd244217e})},
        {Sign::POS, -128, MType({0x89d1b09c70c4010a, 0x8072d72d903d588b})},
        {Sign::POS, -128, MType({0x30d58c3f7e2ea1f, 0x821b05f3b01d6774})},
        {Sign::POS, -128, MType({0x30d58c3f7e2ea1f, 0x821b05f3b01d6774})},
        {Sign::POS, -128, MType({0x20f6fafe8fbb68b9, 0x83c5f8299e2b4091})},
        {Sign::POS, -128, MType({0xe21f9f89c1ab80b2, 0x8573b71682a7d21a})},
        {Sign::POS, -128, MType({0xe21f9f89c1ab80b2, 0x8573b71682a7d21a})},
        {Sign::POS, -128, MType({0x1e005d06dbfa8f8, 0x87244c308e670a66})},
        {Sign::POS, -128, MType({0x223111a707b6de2c, 0x88d7c11e3ad53cdc})},
        {Sign::POS, -128, MType({0x223111a707b6de2c, 0x88d7c11e3ad53cdc})},
        {Sign::POS, -128, MType({0x2eb628dba173c82d, 0x8a8e1fb794b09134})},
        {Sign::POS, -128, MType({0xbe2ad19415fe25a5, 0x8c47720791e53313})},
        {Sign::POS, -128, MType({0xbe2ad19415fe25a5, 0x8c47720791e53313})},
        {Sign::POS, -128, MType({0xbddae1ccce247838, 0x8e03c24d73003959})},
        {Sign::POS, -128, MType({0x9b00bf167e95da67, 0x8fc31afe30b2c6de})},
        {Sign::POS, -128, MType({0x9b00bf167e95da67, 0x8fc31afe30b2c6de})},
        {Sign::POS, -128, MType({0x9b92199ed1a4bab1, 0x918586c5f5e4bf01})},
        {Sign::POS, -128, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
        {Sign::POS, -128, MType({0xdf5bb3b60554e152, 0x934b1089a6dc93c1})},
        {Sign::POS, -128, MType({0xf3cbc416a2418012, 0x9513c36876083695})},
        {Sign::POS, -128, MType({0xbe1188fbc94e2f15, 0x96dfaabd86fa1646})},
        {Sign::POS, -128, MType({0xbe1188fbc94e2f15, 0x96dfaabd86fa1646})},
        {Sign::POS, -128, MType({0x1d2f89321647b358, 0x98aed221a03458b6})},
        {Sign::POS, -128, MType({0x1d2f89321647b358, 0x98aed221a03458b6})},
        {Sign::POS, -128, MType({0xe549f9aaea3cb5e1, 0x9a81456cec642e0f})},
        {Sign::POS, -128, MType({0xa2554b2dd4619e63, 0x9c5710b8cbb73a42})},
        {Sign::POS, -128, MType({0xa2554b2dd4619e63, 0x9c5710b8cbb73a42})},
        {Sign::POS, -128, MType({0x30603d87b6df81ad, 0x9e304061b5fda919})},
        {Sign::POS, -128, MType({0x30603d87b6df81ad, 0x9e304061b5fda919})},
        {Sign::POS, -128, MType({0x67879c5a30cd1242, 0xa00ce1092e5498c3})},
        {Sign::POS, -128, MType({0xb7efae08e597e16, 0xa1ecff97c91e267b})},
        {Sign::POS, -128, MType({0xb7efae08e597e16, 0xa1ecff97c91e267b})},
        {Sign::POS, -128, MType({0x83594fab088c0d65, 0xa3d0a93f45169a4a})},
        {Sign::POS, -128, MType({0x83594fab088c0d65, 0xa3d0a93f45169a4a})},
        {Sign::POS, -128, MType({0xaf6a62a0dec6e073, 0xa5b7eb7cb860fb88})},
        {Sign::POS, -128, MType({0xaf6a62a0dec6e073, 0xa5b7eb7cb860fb88})},
        {Sign::POS, -128, MType({0x49362382a768847a, 0xa7a2d41ad270c9d7})},
        {Sign::POS, -128, MType({0x49362382a768847a, 0xa7a2d41ad270c9d7})},
        {Sign::POS, -128, MType({0x8ba4aea614d05701, 0xa991713433c2b998})},
        {Sign::POS, -128, MType({0x8ba4aea614d05701, 0xa991713433c2b998})},
        {Sign::POS, -128, MType({0x7fe6607ba902ef3c, 0xab83d135dc633301})},
        {Sign::POS, -128, MType({0x7fe6607ba902ef3c, 0xab83d135dc633301})},
        {Sign::POS, -128, MType({0xd60864fd949b4bd3, 0xad7a02e1b24efd31})},
        {Sign::POS, -128, MType({0xd60864fd949b4bd3, 0xad7a02e1b24efd31})},
        {Sign::POS, -128, MType({0x66d235ee63073dd, 0xaf74155120c9011c})},
        {Sign::POS, 0, MType(0)},
    },
    // -log(r) for the second step, generated by SageMath with:
    //
    // for i in range(-2^6, 2^7 + 1):
    //   r = 2^-16 * round( 2^16 / (1 + i*2^(-14)) );
    //   s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
    //   print("{Sign::POS," if s == -1 else "{Sign::NEG,", e, ",
    //         MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
    /* .step_2 = */
    {
        {Sign::NEG, -135, MType({0xa1c6f3fc242ef8d0, 0x803faacac419abf2})},
        {Sign::NEG, -136, MType({0xa225ebc02e6d9dd4, 0xfc834da16f0d9f57})},
        {Sign::NEG, -136, MType({0xc33f6ad340ae18a9, 0xf88735ccc7433381})},
        {Sign::NEG, -136, MType({0x70b2a4d38a242244, 0xf48b0e171249b6bc})},
        {Sign::NEG, -136, MType({0x1d54819048b811b0, 0xf08ed67fd190e280})},
        {Sign::NEG, -136, MType({0xaee5983701d2a02b, 0xec928f0686828706})},
        {Sign::NEG, -136, MType({0x40abb8ab72afa2d2, 0xe89637aab2828aed})},
        {Sign::NEG, -136, MType({0xdeb547a0d4a26ef9, 0xe499d06bd6eeead5})},
        {Sign::NEG, -136, MType({0x39c5bdfbcf6087a0, 0xe09d5949751fb909})},
        {Sign::NEG, -136, MType({0x53ea9bf152de635f, 0xdca0d2430e671d18})},
        {Sign::NEG, -136, MType({0x25b820436f5f4352, 0xd8a43b582411537e})},
        {Sign::NEG, -136, MType({0x3c2d13ea1d0be058, 0xd4a794883764ad41})},
        {Sign::NEG, -136, MType({0x4f3cfa62bcb3ce3a, 0xd0aaddd2c9a18f95})},
        {Sign::NEG, -136, MType({0xd0fff6cdf14a86c7, 0xccae17375c02737c})},
        {Sign::NEG, -136, MType({0x7587b5f0453ac3d2, 0xc8b140b56fbbe56a})},
        {Sign::NEG, -136, MType({0xb358ad16dfd0d085, 0xc4b45a4c85fc84e2})},
        {Sign::NEG, -136, MType({0x3c86fdce5dbe7314, 0xc0b763fc1fed041d})},
        {Sign::NEG, -136, MType({0x70764e46ac18a96d, 0xbcba5dc3beb027a6})},
        {Sign::NEG, -136, MType({0xc63be62b8f285882, 0xb8bd47a2e362c600})},
        {Sign::NEG, -136, MType({0x72e7b5a386e5e31b, 0xb3c0d59a244325a4})},
        {Sign::NEG, -136, MType({0xc3ea2cd93f316b34, 0xafc39bac66434f27})},
        {Sign::NEG, -136, MType({0x1dfb11a7cc892843, 0xabc651d491a7b438})},
        {Sign::NEG, -136, MType({0xfc679a28e9d9f212, 0xa7c8f8122773f38d})},
        {Sign::NEG, -136, MType({0xe7bc977eeec42254, 0xa3cb8e64a8a5bbe6})},
        {Sign::NEG, -136, MType({0xb20f215bd3b58c61, 0x9fce14cb9634cba6})},
        {Sign::NEG, -136, MType({0xabe2862508d67a98, 0x9bd08b467112f078})},
        {Sign::NEG, -136, MType({0xd1aacedcefe9d377, 0x97d2f1d4ba2c06f0})},
        {Sign::NEG, -136, MType({0xf1eb25e77d05f58d, 0x93d54875f265fa2c})},
        {Sign::NEG, -136, MType({0xcbef6fac33691e95, 0x8fd78f299aa0c375})},
        {Sign::NEG, -136, MType({0x2720640462a0f8ad, 0x8bd9c5ef33b669e0})},
        {Sign::NEG, -136, MType({0xe2f1775134c8da75, 0x87dbecc63e7b01ed})},
        {Sign::NEG, -136, MType({0xff67e201c8c50d67, 0x83de03ae3bbcad2e})},
        {Sign::NEG, -137, MType({0x3c742a7c76356396, 0xffc0154d588733c5})},
        {Sign::NEG, -137, MType({0xf90dd6b24aa686ec, 0xf7c4035e21a4052f})},
        {Sign::NEG, -137, MType({0xca47c52b7d7ffce2, 0xefc7d18dd4485b9e})},
        {Sign::NEG, -137, MType({0x3703617ad3d8311f, 0xe7cb7fdb71e0db36})},
        {Sign::NEG, -137, MType({0x7e4cfbd830393b88, 0xdfcf0e45fbce3e80})},
        {Sign::NEG, -137, MType({0x4f7a29cf0fc2c38e, 0xd7d27ccc736555af})},
        {Sign::NEG, -137, MType({0x7370ae83f9e72748, 0xcfd5cb6dd9ef05dd})},
        {Sign::NEG, -137, MType({0x671486eb4cd76f65, 0xc7d8fa2930a84850})},
        {Sign::NEG, -137, MType({0xe6dbb624f9739782, 0xbfdc08fd78c229b9})},
        {Sign::NEG, -137, MType({0x6b866e09e57d9079, 0xb7def7e9b361c979})},
        {Sign::NEG, -137, MType({0x97fa2fd0c9dc723e, 0xafe1c6ece1a058dd})},
        {Sign::NEG, -137, MType({0x983e80897cf1e60f, 0xa7e47606048b1a65})},
        {Sign::NEG, -137, MType({0x7199cd06ae5d39b3, 0x9fe705341d236102})},
        {Sign::NEG, -137, MType({0x43cd18a72a051a96, 0x97e974762c5e8f58})},
        {Sign::NEG, -137, MType({0x7b6d1248c3e1fd40, 0x8febc3cb332616ff})},
        {Sign::NEG, -137, MType({0xf5572a8814c703af, 0x87edf332325777c5})},
        {Sign::NEG, -138, MType({0x26828c92649a3a39, 0xffe0055455887de0})},
        {Sign::NEG, -138, MType({0x82c550bd1216d82a, 0xefe3e4643a640cf3})},
        {Sign::NEG, -138, MType({0xda6959f7f0e01bf0, 0xdfe7839214b4e8ae})},
        {Sign::NEG, -138, MType({0xda93e2fa85a8f214, 0xcfeae2dbe5d6736d})},
        {Sign::NEG, -138, MType({0xb47505bfa5a03b06, 0xbfee023faf0c2480})},
        {Sign::NEG, -138, MType({0xb1475a5180a43520, 0xaff0e1bb718186ad})},
        {Sign::NEG, -138, MType({0xa8740b91c95df537, 0x9ff3814d2e4a36b2})},
        {Sign::NEG, -138, MType({0x57d895d35921b59c, 0x8ff5e0f2e661e1c6})},
        {Sign::NEG, -139, MType({0x3c56c598c659c2a3, 0xfff0015535588833})},
        {Sign::NEG, -139, MType({0x2ef8ec33ed9d782a, 0xdff3c0e497ea4eb1})},
        {Sign::NEG, -139, MType({0x379eba7e6465ff63, 0xbff7008ff5e0c257})},
        {Sign::NEG, -139, MType({0x3f972b783fcab757, 0x9ff9c0535073a370})},
        {Sign::NEG, -140, MType({0xde026e271ee0549d, 0xfff8005551558885})},
        {Sign::NEG, -140, MType({0xeceb47ea01f6c632, 0xbffb8023febc0c25})},
        {Sign::NEG, -141, MType({0x7333c57857e1ed52, 0xfffc001554d55888})},
        {Sign::NEG, -142, MType({0x87dde026fa704374, 0xfffe000555455588})},
        {Sign::NEG, 0, MType({0x0, 0x0})},
        {Sign::POS, -141, MType({0x44999abe2fe2cc65, 0x80010002aab2aac4})},
        {Sign::POS, -140, MType({0x4eef381581464ccb, 0x8002000aaaeaac44})},
        {Sign::POS, -140, MType({0xdfeb485085f6f454, 0xc004802401440c26})},
        {Sign::POS, -139, MType({0x99abe3be3a1c6e93, 0x8004002aacaac445})},
        {Sign::POS, -139, MType({0x6bc1e20eac8448b4, 0xa00640535a37a37a})},
        {Sign::POS, -139, MType({0x979eedc064c242fd, 0xc00900900a20c275})},
        {Sign::POS, -139, MType({0xc72446cc1bf728bd, 0xe00c40e4bd6e4efd})},
        {Sign::POS, -138, MType({0xf381b821bbb569e5, 0x800800aabaac446e})},
        {Sign::POS, -138, MType({0x569b26aaa485ea5c, 0x900a20f319a3e273})},
        {Sign::POS, -138, MType({0x2dcf56c83c80b028, 0xa00c814d7c6a37f8})},
        {Sign::POS, -138, MType({0x5f69768284463b9b, 0xb00f21bbe3e388ee})},
        {Sign::POS, -138, MType({0xb48ea6c05e2773a1, 0xc0120240510c284c})},
        {Sign::POS, -138, MType({0x14d9d76196d8043a, 0xd01522dcc4f87991})},
        {Sign::POS, -138, MType({0xe016a611a4415d72, 0xe018839340d4f241})},
        {Sign::POS, -138, MType({0x661e135f49a47c40, 0xf01c2465c5e61b6f})},
        {Sign::POS, -137, MType({0xbe6bf0fa435e8383, 0x801002ab2ac4499a})},
        {Sign::POS, -137, MType({0x9a31ba0cbc030353, 0x881213337898871e})},
        {Sign::POS, -137, MType({0x54b57dfe0c4c840f, 0x901443cccd362c9f})},
        {Sign::POS, -137, MType({0x7ad1e9c315328f7e, 0x98169478296fad41})},
        {Sign::POS, -137, MType({0x1f3f686cf3d6be22, 0xa01905368e2389b3})},
        {Sign::POS, -137, MType({0xf105b66ec4703ede, 0xa81b9608fc3c50ec})},
        {Sign::POS, -137, MType({0x610848c68df4d233, 0xb01e46f074b0a0f3})},
        {Sign::POS, -137, MType({0xd6aef30cd312169a, 0xb82117edf8832797})},
        {Sign::POS, -137, MType({0xf3ac379608053d9d, 0xc024090288c2a339})},
        {Sign::POS, -137, MType({0xe6e2acf8f4d4c24a, 0xc8271a2f2689e388})},
        {Sign::POS, -137, MType({0xce6ae474d860359f, 0xd02a4b74d2ffca44})},
        {Sign::POS, -137, MType({0x28bb3cd9f2a65fb5, 0xd82d9cd48f574c00})},
        {Sign::POS, -137, MType({0x54f30dbef38a8066, 0xe0310e4f5ccf70e1})},
        {Sign::POS, -137, MType({0x224a96f5a7471c46, 0xe8349fe63cb35564})},
        {Sign::POS, -137, MType({0x6ea920591aa02e1b, 0xf038519a305a2b1b})},
        {Sign::POS, -137, MType({0xd462b63756c87e80, 0xf83c236c39273972})},
        {Sign::POS, -136, MType({0x338f77605fe77f2a, 0x80200aaeac44ef38})},
        {Sign::POS, -136, MType({0x3ff51287882500ed, 0x842213b747fec7bb})},
        {Sign::POS, -136, MType({0xcc394b3ef0ebeb12, 0x88242cd07084ed02})},
        {Sign::POS, -136, MType({0x1ab9679b55f78a6b, 0x8c2655faa6a1323f})},
        {Sign::POS, -136, MType({0x7025697d10af0436, 0x90288f366b237771})},
        {Sign::POS, -136, MType({0x17e4b7ac6c600cb4, 0x942ad8843ee1a9cd})},
        {Sign::POS, -136, MType({0x7013925a9a8da7f3, 0x982d31e4a2b7c418})},
        {Sign::POS, -136, MType({0xfd1a09c848e3950e, 0x9c2f9b581787cf0d})},
        {Sign::POS, -136, MType({0x84dd2de6e3d90a37, 0xa03214df1e39e1bd})},
        {Sign::POS, -136, MType({0x318b2ddd9d0a33b4, 0xa4349e7a37bc21ed})},
        {Sign::POS, -136, MType({0xbc031e6f5acfd4a8, 0xa8373829e502c47a})},
        {Sign::POS, -136, MType({0x9dd91e52c79fd070, 0xac39e1eea7080dbc})},
        {Sign::POS, -136, MType({0x4af78fa1cb48a12d, 0xb03c9bc8fecc51e3})},
        {Sign::POS, -136, MType({0x72de1d99ce252efd, 0xb43f65b96d55f55a})},
        {Sign::POS, -136, MType({0xefb1dbe721934877, 0xb74187bc8ccffa84})},
        {Sign::POS, -136, MType({0xb4b080f230c87598, 0xbb446dd4d9bca499})},
        {Sign::POS, -136, MType({0xda6a7cd19c7fa4f2, 0xbf476404a05f88f2})},
        {Sign::POS, -136, MType({0xdf00e3783b50ecfb, 0xc34a6a4c61d5cc3c})},
        {Sign::POS, -136, MType({0xda2e5e02ab4e183c, 0xc74d80ac9f42a52d})},
        {Sign::POS, -136, MType({0xea5f6ee99d30c626, 0xcb50a725d9cf5ce6})},
        {Sign::POS, -136, MType({0xa96d5956531d7d8b, 0xcf53ddb892ab4f55})},
        {Sign::POS, -136, MType({0xa8fc636eb36afa75, 0xd35724654b0beb95})},
        {Sign::POS, -136, MType({0xf67e2b827bfc4421, 0xd75a7b2c842cb451})},
        {Sign::POS, -136, MType({0xa6d8c817516303e6, 0xdb5de20ebf4f4026})},
        {Sign::POS, -136, MType({0x69b36ae5962e85f4, 0xdf61590c7dbb3a02})},
        {Sign::POS, -136, MType({0x24693eec2a831cc3, 0xe364e02640be6188})},
        {Sign::POS, -136, MType({0x94a339d56a55ab4a, 0xe768775c89ac8b70})},
        {Sign::POS, -136, MType({0xfa9998fbf9703bf4, 0xeb6c1eafd9dfa1eb})},
        {Sign::POS, -136, MType({0xcafdc27227b71eaa, 0xef6fd620b2b7a503})},
        {Sign::POS, -136, MType({0x688d4282f6026aa3, 0xf3739daf959aaafc})},
        {Sign::POS, -136, MType({0xe54e9e3804464cdd, 0xf777755d03f4e0b6})},
        {Sign::POS, -136, MType({0xcb78b383f4b59dce, 0xfb7b5d297f388a12})},
        {Sign::POS, -136, MType({0xee055fc515062c04, 0xff7f551588de024f})},
        {Sign::POS, -135, MType({0x207812b43382acdd, 0x81c1ae90d131de38})},
        {Sign::POS, -135, MType({0xdc90c4c4b61f3a87, 0x83c3baa726a721cc})},
        {Sign::POS, -135, MType({0x1a03f13fb2c978b1, 0x85c5cece05941dbc})},
        {Sign::POS, -135, MType({0xb36f282e83a7dc36, 0x87c7eb05aec1304f})},
        {Sign::POS, -135, MType({0x6ad14c3dfa414391, 0x89ca0f4e62f9c476})},
        {Sign::POS, -135, MType({0xe8dd4ea0d48b88e5, 0x8bcc3ba8630c51f4})},
        {Sign::POS, -135, MType({0xc02515afe8caeb90, 0x8dce7013efca5d96})},
        {Sign::POS, -135, MType({0x741ceaf3349f3cf1, 0x8fd0ac914a08795f})},
        {Sign::POS, -135, MType({0x83f7cd4929d2c28c, 0x91d2f120b29e44bb})},
        {Sign::POS, -135, MType({0x795d03ebc2fd03fa, 0x93d53dc26a666cb1})},
        {Sign::POS, -135, MType({0xfaf74f1d1ad16acc, 0x95d79276b23eac12})},
        {Sign::POS, -135, MType({0xe2de134f72fee429, 0x97d9ef3dcb07cbad})},
        {Sign::POS, -135, MType({0x58d8dba6cadac5d5, 0x99dc5417f5a5a27d})},
        {Sign::POS, -135, MType({0xf07d90bc5aae40a4, 0x9bdec10572ff15da})},
        {Sign::POS, -135, MType({0x1deaf79d9fc40374, 0x9d6098046659ea6b})},
        {Sign::POS, -135, MType({0x7ba63e6769b81999, 0x9f63131450b07988})},
        {Sign::POS, -135, MType({0x59ebfc9335094e59, 0xa1659638404d5f92})},
        {Sign::POS, -135, MType({0x16aae012b5026f71, 0xa36821707622f97a})},
        {Sign::POS, -135, MType({0xff5d4f2c0e4b9cae, 0xa56ab4bd3326b378})},
        {Sign::POS, -135, MType({0x855838b5119dcb28, 0xa76d501eb8510941})},
        {Sign::POS, -135, MType({0x75f70cbbe9cf1603, 0xa96ff395469d8630})},
        {Sign::POS, -135, MType({0x36a53ad4d5541cc9, 0xab729f211f0ac57e})},
        {Sign::POS, -135, MType({0x4c5934ec32d20d9, 0xad7552c2829a7270})},
        {Sign::POS, -135, MType({0x3977e89aec59bfa2, 0xaf780e79b2514889})},
        {Sign::POS, -135, MType({0x913d4e3dc55c3e6e, 0xb17ad246ef3713bc})},
        {Sign::POS, -135, MType({0x777b52a9e70d8bcc, 0xb37d9e2a7a56b09d})},
        {Sign::POS, -135, MType({0x55de916fd30591de, 0xb580722494be0c91})},
        {Sign::POS, -135, MType({0xe79cfb37be2861e4, 0xb7834e357f7e2600})},
        {Sign::POS, -135, MType({0x90983104d3805389, 0xb986325d7bab0c89})},
        {Sign::POS, -135, MType({0xb860504baa6f984d, 0xbb891e9cca5be12e})},
        {Sign::POS, -135, MType({0x29178d6ff5712b96, 0xbd8c12f3acaad68b})},
        {Sign::POS, -135, MType({0x7236fa47ba19a198, 0xbf8f0f6263b53102})},
        {Sign::POS, -135, MType({0x4f34d64cafcc50e3, 0xc19213e9309b46f2})},
        {Sign::POS, -135, MType({0x120cc62eb0a8db3e, 0xc3952088548080e4})},
        {Sign::POS, -135, MType({0x11aa5084779060e3, 0xc5983540108b59be})},
        {Sign::POS, -135, MType({0x1c35fd6236c8dcf1, 0xc79b5210a5e55ef5})},
        {Sign::POS, -135, MType({0xed4576a7e4b878fe, 0xc99e76fa55bb30bd})},
        {Sign::POS, -135, MType({0x6caf4bb8fd2c1131, 0xcb20d7fa3a336081})},
        {Sign::POS, -135, MType({0x3f24a6cbb09c654f, 0xcd240b10753e78de})},
        {Sign::POS, -135, MType({0x78bc003bb81e40f3, 0xcf2746407e0ff09f})},
        {Sign::POS, -135, MType({0x56647301edfd8e8b, 0xd12a898a95dff002})},
        {Sign::POS, -135, MType({0x28fe1c4d04ca4ed9, 0xd32dd4eefde9b2ef})},
        {Sign::POS, -135, MType({0xe1ea9ea6cbf57379, 0xd531286df76b892a})},
        {Sign::POS, -135, MType({0xa3832028141a5cc2, 0xd7348407c3a6d688})},
        {Sign::POS, -135, MType({0x557421dd379d3ead, 0xd937e7bca3e0131b})},
        {Sign::POS, -135, MType({0x3cff8e87a99bcaf0, 0xdb3b538cd95ecb67})},
        {Sign::POS, -135, MType({0x99255ef34bd0801f, 0xdd3ec778a56da093})},
        {Sign::POS, -135, MType({0x42b33220abfa15cd, 0xdf424380495a489c})},
        {Sign::POS, -135, MType({0x503b378faa97dbc0, 0xe145c7a406758e83})},
        {Sign::POS, -135, MType({0xbdf2ca006f59b544, 0xe34953e41e135282})},
        {Sign::POS, -135, MType({0x1979190af37ed16f, 0xe54ce840d18a8a3e})},
        {Sign::POS, -135, MType({0x31863ff7cf898c9c, 0xe75084ba623540f4})},
        {Sign::POS, -135, MType({0xc983284f60293647, 0xe9542951117097b0})},
        {Sign::POS, -135, MType({0x510a969ebe03f804, 0xeb57d605209cc57e})},
        {Sign::POS, -135, MType({0x9f53bffc6d23fe30, 0xed5b8ad6d11d1797})},
        {Sign::POS, -135, MType({0xb286c6e113337886, 0xef5f47c66457f199})},
        {Sign::POS, -135, MType({0xb6ed80852ae6fd63, 0xf0e21acdd6e7d412})},
        {Sign::POS, -135, MType({0xdf437fb0f616082d, 0xf2e5e5f25450c5a2})},
        {Sign::POS, -135, MType({0xf237cff1acb306b3, 0xf4e9b935685dbe0b})},
        {Sign::POS, -135, MType({0x52dbfafb4121a092, 0xf6ed94975480b696})},
        {Sign::POS, -135, MType({0xd81648249cece4c, 0xf8f178185a2ebfd9})},
        {Sign::POS, -135, MType({0xad95e6b0b96903d3, 0xfaf563b8bae001eb})},
        {Sign::POS, -135, MType({0x176cd56887ac7fe9, 0xfcf95778b80fbc98})},
        {Sign::POS, -135, MType({0x65f4c7397f1f478d, 0xfefd5358933c478c})},
    },
    // -log(r) for the third step, generated by SageMath with:
    //
    // for i in range(-80, 81):
    //   r = 2^-21 * round( 2^21 / (1 + i*2^(-21)) );
    //   s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
    //   print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
    //         MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
    /* .step_3 = */
    {
        {Sign::NEG, -142, MType({0x374b294076d669c3, 0x9fff38014d52e45a})},
        {Sign::NEG, -142, MType({0x7f6f05dcdbeb776e, 0x9dff3cf940fad85a})},
        {Sign::NEG, -142, MType({0x3d55e21d41bbadf9, 0x9bff41e134f1cb36})},
        {Sign::NEG, -142, MType({0xccdba2d54aadbc5c, 0x99ff46b92936bcf4})},
        {Sign::NEG, -142, MType({0x71dd16d3073f79b2, 0x97ff4b811dc8ad9d})},
        {Sign::NEG, -142, MType({0x5837f3df1a58dd48, 0x95ff503912a69d37})},
        {Sign::NEG, -142, MType({0x93cad3bcdd26fd6d, 0x93ff54e107cf8bc9})},
        {Sign::NEG, -142, MType({0x2075312a827f14fa, 0x91ff5978fd42795b})},
        {Sign::NEG, -142, MType({0xe21764e139c98f60, 0x8fff5e00f2fe65f2})},
        {Sign::NEG, -142, MType({0xa492a29551751b4c, 0x8dff6278e9025197})},
        {Sign::NEG, -142, MType({0x1bc8f5f658f1c3a2, 0x8bff66e0df4d3c50})},
        {Sign::NEG, -142, MType({0xe39d3faf42340ed7, 0x89ff6b38d5de2622})},
        {Sign::NEG, -142, MType({0x7ff3326682c02485, 0x87ff6f80ccb40f16})},
        {Sign::NEG, -142, MType({0x5caf4fbe343cf928, 0x85ff73b8c3cdf731})},
        {Sign::NEG, -142, MType({0xcdb6e554348f7fe8, 0x83ff77e0bb2ade79})},
        {Sign::NEG, -142, MType({0xef009c2457de25d, 0x81ff7bf8b2c9c4f6})},
        {Sign::NEG, -143, MType({0x8883333c57b57c74, 0xffff000155535558})},
        {Sign::NEG, -143, MType({0xf32668f39c70d183, 0xfbff07f145931f44})},
        {Sign::NEG, -143, MType({0x459a73c6a6486fe3, 0xf7ff0fc13650e7bd})},
        {Sign::NEG, -143, MType({0x37b18cca7dd3a29f, 0xf3ff1771278aaecd})},
        {Sign::NEG, -143, MType({0x513f610d21bcfc78, 0xefff1f01193e7480})},
        {Sign::NEG, -143, MType({0xea190b95c0690b7b, 0xebff26710b6a38e1})},
        {Sign::NEG, -143, MType({0x2a150f64f0ad1743, 0xe7ff2dc0fe0bfbfd})},
        {Sign::NEG, -143, MType({0x90b5174e995e9d1, 0xe3ff34f0f121bddd})},
        {Sign::NEG, -143, MType({0x4ed512b9b93ea2bf, 0xdfff3c00e4a97e8c})},
        {Sign::NEG, -143, MType({0x934cea217ab794a2, 0xdbff42f0d8a13e15})},
        {Sign::NEG, -143, MType({0x3e4ebe948afd2c76, 0xd7ff49c0cd06fc83})},
        {Sign::NEG, -143, MType({0x87b7c0f5bcfee2e1, 0xd3ff5070c1d8b9df})},
        {Sign::NEG, -143, MType({0x776666228cb6371b, 0xcfff5700b7147634})},
        {Sign::NEG, -143, MType({0xe53a60f3514db358, 0xcbff5d70acb8318b})},
        {Sign::NEG, -143, MType({0x79149c3b6e57fa86, 0xc7ff63c0a2c1ebef})},
        {Sign::NEG, -143, MType({0xaad734c98416df2a, 0xc3ff69f0992fa568})},
        {Sign::NEG, -143, MType({0xc26573679ed28334, 0xbfff70008fff5e00})},
        {Sign::NEG, -143, MType({0xd7a3c6db6540809f, 0xbbff75f0872f15c0})},
        {Sign::NEG, -143, MType({0xd277bde645fb1aad, 0xb7ff7bc07ebcccb1})},
        {Sign::NEG, -143, MType({0x6ac80145a4087793, 0xb3ff817076a682dc})},
        {Sign::NEG, -143, MType({0x287c4db30271e265, 0xafff87006eea3849})},
        {Sign::NEG, -143, MType({0x637d6de42eeb151e, 0xabff8c706785ed00})},
        {Sign::NEG, -143, MType({0x43b5348b6b898a8c, 0xa7ff91c06077a10a})},
        {Sign::NEG, -143, MType({0xc10e7657978bd7f6, 0xa3ff96f059bd546e})},
        {Sign::NEG, -143, MType({0xa37503f457310e59, 0x9fff9c0053550735})},
        {Sign::NEG, -143, MType({0x82d5a40a3aa022ff, 0x9bffa0f04d3cb966})},
        {Sign::NEG, -143, MType({0xc71e0d3ee3df5f4d, 0x97ffa5c047726b08})},
        {Sign::NEG, -143, MType({0xa83ce0352bdbd79b, 0x93ffaa7041f41c23})},
        {Sign::NEG, -143, MType({0x2e21a18d4680e8e4, 0x8fffaf003cbfccbe})},
        {Sign::NEG, -143, MType({0x30bcb3e4e5dfbd28, 0x8bffb37037d37cdf})},
        {Sign::NEG, -143, MType({0x57ff51d75c66d64a, 0x87ffb7c0332d2c8d})},
        {Sign::NEG, -143, MType({0x1bdb87fdbe299f43, 0x83ffbbf02ecadbcf})},
        {Sign::NEG, -144, MType({0x88885dde02700703, 0xffff800055551555})},
        {Sign::NEG, -144, MType({0xd259ca803a0c1870, 0xf7ff87e04d94724c})},
        {Sign::NEG, -144, MType({0xe514130851c7070a, 0xefff8f80464fce8f})},
        {Sign::NEG, -144, MType({0x30a16898f3073a64, 0xe7ff96e03f832a2a})},
        {Sign::NEG, -144, MType({0xc4ed64517b2949ce, 0xdfff9e00392a8526})},
        {Sign::NEG, -144, MType({0x51e4fb4e32cf6350, 0xd7ffa4e03341df90})},
        {Sign::NEG, -144, MType({0x277672a88350bcce, 0xcfffab802dc53971})},
        {Sign::NEG, -144, MType({0x359153772a490f06, 0xc7ffb1e028b092d3})},
        {Sign::NEG, -144, MType({0xc265ece6b481a0e, 0xbfffb80023ffebc0})},
        {Sign::NEG, -144, MType({0xdb2781c03fa132f6, 0xb7ffbde01faf4440})},
        {Sign::NEG, -144, MType({0x7287c95c845ada33, 0xafffc3801bba9c5e})},
        {Sign::NEG, -144, MType({0x423b56b1263e5a77, 0xa7ffc8e0181df421})},
        {Sign::NEG, -144, MType({0x5a3752ca4c076fa3, 0x9fffce0014d54b91})},
        {Sign::NEG, -144, MType({0x6a71e2b27eb3f573, 0x97ffd2e011dca2b6})},
        {Sign::NEG, -144, MType({0xc2e21b72cff39d8f, 0x8fffd7800f2ff997})},
        {Sign::NEG, -144, MType({0x537ff612feb7ac9e, 0x87ffdbe00ccb503c})},
        {Sign::NEG, -145, MType({0x5888873333c57c18, 0xffffc00015554d55})},
        {Sign::NEG, -145, MType({0xfa51421842311c42, 0xefffc7c01193f9d1})},
        {Sign::NEG, -145, MType({0x2c4ed6de475b942c, 0xdfffcf000e4aa5fa})},
        {Sign::NEG, -145, MType({0xce77678cbb6fcb88, 0xcfffd5c00b7151d8})},
        {Sign::NEG, -145, MType({0xc26629a679ed3b, 0xbfffdc0008fffd78})},
        {Sign::NEG, -145, MType({0x23287cb9d3072728, 0xafffe1c006eea8e1})},
        {Sign::NEG, -145, MType({0xd5a37540fd057315, 0x9fffe7000535541c})},
        {Sign::NEG, -145, MType({0xf82e21c1fce36810, 0x8fffebc003cbff32})},
        {Sign::NEG, -146, MType({0x5588887ddde02702, 0xffffe00005555455})},
        {Sign::NEG, -146, MType({0x9ac4ed72adf5b295, 0xdfffe7800392aa14})},
        {Sign::NEG, -146, MType({0xc26648066b482, 0xbfffee00023fffaf})},
        {Sign::NEG, -146, MType({0x455a3754b292c077, 0x9ffff380014d552e})},
        {Sign::NEG, -147, MType({0x5558888833333c58, 0xfffff00001555535})},
        {Sign::NEG, -147, MType({0xe000c2665736679f, 0xbffff700008ffff5})},
        {Sign::NEG, -148, MType({0x5555888885ddde02, 0xfffff80000555551})},
        {Sign::NEG, -149, MType({0xd555588888733334, 0xfffffc0000155554})},
        {Sign::POS, 0, MType({0x0, 0x0})},
        {Sign::POS, -148, MType({0xeaaaac44444eeeef, 0x80000200000aaaaa})},
        {Sign::POS, -147, MType({0xaaaac444459999ac, 0x80000400002aaaac})},
        {Sign::POS, -147, MType({0x2000c2667596679f, 0xc00009000090000a})},
        {Sign::POS, -146, MType({0xaaac44446eeef381, 0x8000080000aaaaba})},
        {Sign::POS, -146, MType({0x655a3755f81815cc, 0xa0000c80014d557c})},
        {Sign::POS, -146, MType({0xc26684c66b482, 0xc000120002400051})},
        {Sign::POS, -146, MType({0xbac4ed7c40fb07eb, 0xe00018800392ab40})},
        {Sign::POS, -145, MType({0xaac44449999abe2c, 0x8000100002aaab2a})},
        {Sign::POS, -145, MType({0x82e21d79cbb6812, 0x9000144003cc00cd})},
        {Sign::POS, -145, MType({0xd5a37569adb01dc3, 0xa00019000535568d})},
        {Sign::POS, -145, MType({0x33287d01e8c9d1d9, 0xb0001e4006eeac74})},
        {Sign::POS, -145, MType({0xc266a32679ed48, 0xc000240009000288})},
        {Sign::POS, -145, MType({0xde77685122b2764b, 0xd0002a400b7158d1})},
        {Sign::POS, -145, MType({0x2c4ed810a8063f03, 0xe00031000e4aaf5b})},
        {Sign::POS, -145, MType({0xa5143e7be891c8f, 0xf00038401194062e})},
        {Sign::POS, -144, MType({0xac4444eeef3813a1, 0x800020000aaaaeaa})},
        {Sign::POS, -144, MType({0x5b7ff7fe1339025b, 0x880024200ccb5a6e})},
        {Sign::POS, -144, MType({0x42e21e26caf39e33, 0x900028800f300668})},
        {Sign::POS, -144, MType({0xf271e66fa5554bc6, 0x98002d2011dcb29e})},
        {Sign::POS, -144, MType({0x5a3757e0615cc676, 0xa000320014d55f19})},
        {Sign::POS, -144, MType({0xca3b5d8210ca5cab, 0xa8003720181e0bde})},
        {Sign::POS, -144, MType({0xf287d25f3cb032bb, 0xb0003c801bbab8f6})},
        {Sign::POS, -144, MType({0xe3278d840be28cdb, 0xb80042201faf6669})},
        {Sign::POS, -144, MType({0xc266dfe6b482076, 0xc000480024001440})},
        {Sign::POS, -144, MType({0x3d9166de380a6d3d, 0xc8004e2028b0c282})},
        {Sign::POS, -144, MType({0xa7768b356ba61e4b, 0xd00054802dc57139})},
        {Sign::POS, -144, MType({0xd9e51a1849db73c1, 0xd8005b203342206f})},
        {Sign::POS, -144, MType({0xc4ed8a9d907eb521, 0xe0006200392ad02e})},
        {Sign::POS, -144, MType({0xb8a197dea928acd7, 0xe80069203f838080})},
        {Sign::POS, -144, MType({0x65144cf7dcc72d3b, 0xf000708046503170})},
        {Sign::POS, -144, MType({0xda5a1108890d9f6a, 0xf80078204d94e308})},
        {Sign::POS, -143, MType({0xc4445999abe2ce2c, 0x800040002aaacaaa})},
        {Sign::POS, -143, MType({0x1fdbbb4f3bffc832, 0x840044102ecb2431})},
        {Sign::POS, -143, MType({0x97ff8f39ec91b4ee, 0x88004840332d7e1d})},
        {Sign::POS, -143, MType({0x74bcfcf0b3f0a95d, 0x8c004c9037d3d876})},
        {Sign::POS, -143, MType({0x2e21f80ca6813aff, 0x900051003cc03342})},
        {Sign::POS, -143, MType({0x6c3d4629170ce87f, 0x9400559041f48e87})},
        {Sign::POS, -143, MType({0x71e84e3b80a8881, 0x98005a404772ea4d})},
        {Sign::POS, -143, MType({0x6d62fdcbdd6bec3, 0x9c005f104d3d469a})},
        {Sign::POS, -143, MType({0xa375a6b701dc77c0, 0xa00064005355a375})},
        {Sign::POS, -143, MType({0x450f331826ad6b05, 0xa400691059be00e7})},
        {Sign::POS, -143, MType({0x83b60ea8bd0aa459, 0xa8006e4060785ef6})},
        {Sign::POS, -143, MType({0x277e691469dd13f5, 0xac0073906786bdab})},
        {Sign::POS, -143, MType({0x287d6e0a0d1e25eb, 0xb00079006eeb1d0d})},
        {Sign::POS, -143, MType({0xaec94b3be9b060f5, 0xb4007e9076a77d24})},
        {Sign::POS, -143, MType({0x1279365fce280cce, 0xb80084407ebdddfa})},
        {Sign::POS, -143, MType({0xdba5732f3e83e04a, 0xbc008a1087303f95})},
        {Sign::POS, -143, MType({0xc26759679ed5b754, 0xc00090009000a200})},
        {Sign::POS, -143, MType({0xaed95aca5edb5109, 0xc400961099310543})},
        {Sign::POS, -143, MType({0xb917091d2687160f, 0xc8009c40a2c36967})},
        {Sign::POS, -143, MType({0x293d1c2a0378e75d, 0xcc00a290acb9ce76})},
        {Sign::POS, -143, MType({0x776977bf9766f5a7, 0xd000a900b7163478})},
        {Sign::POS, -143, MType({0x4bbb31b14776a18b, 0xd400af90c1da9b78})},
        {Sign::POS, -143, MType({0x7e5297d76c8564ba, 0xd800b640cd09037f})},
        {Sign::POS, -143, MType({0x1751360f8461c447, 0xdc00bd10d8a36c98})},
        {Sign::POS, -143, MType({0x4ed9dc3c63f44c41, 0xe000c400e4abd6cc})},
        {Sign::POS, -143, MType({0x8d10a4466a5894d5, 0xe400cb10f1244226})},
        {Sign::POS, -143, MType({0x6a1af81bb4e6510e, 0xe800d240fe0eaeb1})},
        {Sign::POS, -143, MType({0xae1f97b0542a677a, 0xec00d9910b6d1c77})},
        {Sign::POS, -143, MType({0x51469efe81d014cc, 0xf000e10119418b84})},
        {Sign::POS, -143, MType({0x7bb98c06d77a18b4, 0xf400e891278dfbe2})},
        {Sign::POS, -143, MType({0x85a344d0868bed17, 0xf800f04136546d9d})},
        {Sign::POS, -143, MType({0xf7301d6990e307cc, 0xfc00f8114596e0c0})},
        {Sign::POS, -142, MType({0x4446eef38140138f, 0x80008000aaabaaac})},
        {Sign::POS, -142, MType({0x10f5e43296105497, 0x82008408b2cbe5b8})},
        {Sign::POS, -142, MType({0xedbd4f83ef63f730, 0x84008820bb2d2189})},
        {Sign::POS, -142, MType({0xfeb654fd541c638e, 0x86008c48c3d05e27})},
        {Sign::POS, -142, MType({0x7ffadeb8882f7674, 0x88009080ccb69b98})},
        {Sign::POS, -142, MType({0xc5a59fd36bd44397, 0x8a0094c8d5e0d9e1})},
        {Sign::POS, -142, MType({0x3bd217701b27dddb, 0x8c009920df50190a})},
        {Sign::POS, -142, MType({0x669c93b50e4a2595, 0x8e009d88e9055918})},
        {Sign::POS, -142, MType({0xe22234cd39f29cd4, 0x9000a200f3019a12})},
        {Sign::POS, -142, MType({0x6280efe8307d41d9, 0x9200a688fd45dc00})},
        {Sign::POS, -142, MType({0xb3d7923a436f6fc4, 0x9400ab2107d31ee7})},
        {Sign::POS, -142, MType({0xba45c3fca574c5a0, 0x9600afc912aa62cf})},
        {Sign::POS, -142, MType({0x71ec0b6d8cd413d1, 0x9800b4811dcca7bf})},
        {Sign::POS, -142, MType({0xeeebcfd0565c5006, 0x9a00b949293aedbd})},
        {Sign::POS, -142, MType({0x5d675c6da8c98fc3, 0x9c00be2134f634d2})},
        {Sign::POS, -142, MType({0x181e39398a2099a, 0x9e00c30940ff7d04})},
        {Sign::POS, -142, MType({0x375f8195cc8b1d29, 0xa000c8014d57c65a})},

    },
    // -log(r) for the fourth step, generated by SageMath with:
    //
    // for i in range(-65, 65):
    //   r = 2^-28 * round( 2^28 / (1 + i*2^(-28)) );
    //   s, m, e = RealField(128)(r).log().sign_mantissa_exponent();
    //   print("{Sign::POS," if (s == -1) else "{Sign::NEG,", e, ",
    //         MType({", hex(m % 2^64), ",", hex((m >> 64) % 2^64), "})},");
    /* .step_4 = */
    {
        {Sign::NEG, -149, MType({0x4cd24d68ff2f11ae, 0x81fffef7f002cb2b})},
        {Sign::NEG, -150, MType({0x455555888887ddde, 0xfffffe0000055555})},
        {Sign::NEG, -150, MType({0xf0fa101f52b3971f, 0xfbfffe0fe0051653})},
        {Sign::NEG, -150, MType({0x9c9329d659ed3734, 0xf7fffe1f8004d94a})},
        {Sign::NEG, -150, MType({0x4821006d9b58462e, 0xf3fffe2ee0049e31})},
        {Sign::NEG, -150, MType({0xf3a3f025142f8c21, 0xeffffe3e000464ff})},
        {Sign::NEG, -150, MType({0x9f1c53bcc1c4b11c, 0xebfffe4ce0042dae})},
        {Sign::NEG, -150, MType({0x4a8a8474a17fdd30, 0xe7fffe5b8003f835})},
        {Sign::NEG, -150, MType({0xf5eeda0cb0df586d, 0xe3fffe69e003c48b})},
        {Sign::NEG, -150, MType({0xa149aac4ed772adf, 0xdffffe78000392aa})},
        {Sign::NEG, -150, MType({0x4c9b4b5d54f0bc96, 0xdbfffe85e0036289})},
        {Sign::NEG, -150, MType({0xf7e40f15e50a759f, 0xd7fffe938003341f})},
        {Sign::NEG, -150, MType({0xa32447ae9b975e05, 0xd3fffea0e0030766})},
        {Sign::NEG, -150, MType({0x4e5c4567767ebdd5, 0xcffffeae0002dc55})},
        {Sign::NEG, -150, MType({0xf98c570073bbbd19, 0xcbfffebae002b2e3})},
        {Sign::NEG, -150, MType({0xa4b4c9b9915d03dd, 0xc7fffec780028b0a})},
        {Sign::NEG, -150, MType({0x4fd5e952cd845a28, 0xc3fffed3e00264c1})},
        {Sign::NEG, -150, MType({0xfaf0000c26664806, 0xbffffee000023fff})},
        {Sign::NEG, -150, MType({0xa60356a59a49b57f, 0xbbfffeebe0021cbe})},
        {Sign::NEG, -150, MType({0x5110345f27878a9b, 0xb7fffef78001faf5})},
        {Sign::NEG, -150, MType({0xfc16def8cc8a4f61, 0xb3ffff02e001da9b})},
        {Sign::NEG, -150, MType({0xa7179ab287cdcbd8, 0xafffff0e0001bbaa})},
        {Sign::NEG, -150, MType({0x5212aa4c57dea809, 0xabffff18e0019e19})},
        {Sign::NEG, -150, MType({0xfd084f063b5a0bf8, 0xa7ffff23800181df})},
        {Sign::NEG, -150, MType({0xa7f8c8a030ed3fab, 0xa3ffff2de00166f6})},
        {Sign::NEG, -150, MType({0x52e4555a37554b29, 0x9fffff3800014d55})},
        {Sign::NEG, -150, MType({0xfdcb31f44d5e9676, 0x9bffff41e00134f3})},
        {Sign::NEG, -150, MType({0xa8ad99ae71e48997, 0x97ffff4b80011dca})},
        {Sign::NEG, -150, MType({0x538bc648a3d12c90, 0x93ffff54e00107d1})},
        {Sign::NEG, -150, MType({0xfe65f002e21cc765, 0x8fffff5e0000f2ff})},
        {Sign::NEG, -150, MType({0xa93c4d9d2bcd821a, 0x8bffff66e000df4e})},
        {Sign::NEG, -150, MType({0x540f14577ff704b2, 0x87ffff6f8000ccb5})},
        {Sign::NEG, -150, MType({0xfede77f1ddba1731, 0x83ffff77e000bb2b})},
        {Sign::NEG, -151, MType({0x5355555888888333, 0xffffff0000015555})},
        {Sign::NEG, -151, MType({0xa8e7ba8d659ed7dc, 0xf7ffff0fc0013652})},
        {Sign::NEG, -151, MType({0xfe747e025142fc61, 0xefffff1f0001193f})},
        {Sign::NEG, -151, MType({0x53fbfb374a1800c7, 0xe7ffff2dc000fe0d})},
        {Sign::NEG, -151, MType({0xa97e8aac4ed77513, 0xdfffff3c0000e4aa})},
        {Sign::NEG, -151, MType({0xfefc81e15e50a947, 0xd7ffff49c000cd07})},
        {Sign::NEG, -151, MType({0x547633567767ed66, 0xcfffff570000b715})},
        {Sign::NEG, -151, MType({0xa9ebee8b9915d174, 0xc7ffff63c000a2c2})},
        {Sign::NEG, -151, MType({0xff5e0000c2666573, 0xbfffff7000008fff})},
        {Sign::NEG, -151, MType({0x54ccb135f2787966, 0xb7ffff7bc0007ebd})},
        {Sign::NEG, -151, MType({0xaa3848ab287cdd4e, 0xafffff8700006eea})},
        {Sign::NEG, -151, MType({0xffa109e063b5a12d, 0xa7ffff91c0006077})},
        {Sign::NEG, -151, MType({0x55073555a3755504, 0x9fffff9c00005355})},
        {Sign::NEG, -151, MType({0xaa6b088ae71e48d5, 0x97ffffa5c0004772})},
        {Sign::NEG, -151, MType({0xffccbe002e21cca2, 0x8fffffaf00003cbf})},
        {Sign::NEG, -151, MType({0x552c8d3577ff706a, 0x87ffffb7c000332d})},
        {Sign::NEG, -152, MType({0x551555558888885e, 0xffffff8000005555})},
        {Sign::NEG, -152, MType({0xffce8fc025142fe3, 0xefffff8f8000464f})},
        {Sign::NEG, -152, MType({0xaa8526aac4ed7764, 0xdfffff9e0000392a})},
        {Sign::NEG, -152, MType({0x5539711567767ee3, 0xcfffffab80002dc5})},
        {Sign::NEG, -152, MType({0xffebc0000c26665f, 0xbfffffb8000023ff})},
        {Sign::NEG, -152, MType({0xaa9c5e6ab287cdd9, 0xafffffc380001bba})},
        {Sign::NEG, -152, MType({0x554b91555a375553, 0x9fffffce000014d5})},
        {Sign::NEG, -152, MType({0xfff997c002e21ccb, 0x8fffffd780000f2f})},
        {Sign::NEG, -153, MType({0x554d555558888887, 0xffffffc000001555})},
        {Sign::NEG, -153, MType({0xaaa5fa2aac4ed777, 0xdfffffcf00000e4a})},
        {Sign::NEG, -153, MType({0xfffd780000c26666, 0xbfffffdc000008ff})},
        {Sign::NEG, -153, MType({0x55541cd555a37555, 0x9fffffe700000535})},
        {Sign::NEG, -154, MType({0x5554555555888888, 0xffffffe000000555})},
        {Sign::NEG, -154, MType({0xffffaf00000c2666, 0xbfffffee0000023f})},
        {Sign::NEG, -155, MType({0x5555355555588889, 0xfffffff000000155})},
        {Sign::NEG, -156, MType({0x5555515555558889, 0xfffffff800000055})},
        {Sign::POS, 0, MType({0x0, 0x0})},
        {Sign::POS, -155, MType({0xaaaaacaaaaaac444, 0x800000040000002a})},
        {Sign::POS, -154, MType({0xaaaabaaaaaac4444, 0x80000008000000aa})},
        {Sign::POS, -154, MType({0x5100000c2666, 0xc000001200000240})},
        {Sign::POS, -153, MType({0xaaab2aaaaac44444, 0x80000010000002aa})},
        {Sign::POS, -153, MType({0x55568dd555a37555, 0xa000001900000535})},
        {Sign::POS, -153, MType({0x2880000c26667, 0xc000002400000900})},
        {Sign::POS, -153, MType({0xaaaf5b2aac4ed778, 0xe000003100000e4a})},
        {Sign::POS, -152, MType({0xaaaeaaaaac444445, 0x8000002000000aaa})},
        {Sign::POS, -152, MType({0x6684002e21cce, 0x9000002880000f30})},
        {Sign::POS, -152, MType({0x555f19555a375558, 0xa0000032000014d5})},
        {Sign::POS, -152, MType({0xaab8f6eab287cde2, 0xb000003c80001bba})},
        {Sign::POS, -152, MType({0x1440000c26666e, 0xc000004800002400})},
        {Sign::POS, -152, MType({0x5571399567767efb, 0xd000005480002dc5})},
        {Sign::POS, -152, MType({0xaad02eaac4ed778b, 0xe00000620000392a})},
        {Sign::POS, -152, MType({0x3170402514301d, 0xf000007080004650})},
        {Sign::POS, -151, MType({0xaacaaaaac444445a, 0x8000004000002aaa})},
        {Sign::POS, -151, MType({0x557e1d7577ff70a7, 0x880000484000332d})},
        {Sign::POS, -151, MType({0x3342002e21ccf8, 0x9000005100003cc0})},
        {Sign::POS, -151, MType({0xaaea4ccae71e494d, 0x9800005a40004772})},
        {Sign::POS, -151, MType({0x55a37555a37555a7, 0xa000006400005355})},
        {Sign::POS, -151, MType({0x5ef62063b5a207, 0xa800006e40006078})},
        {Sign::POS, -151, MType({0xab1d0cab287cde6e, 0xb000007900006eea})},
        {Sign::POS, -151, MType({0x55ddf975f2787ade, 0xb800008440007ebd})},
        {Sign::POS, -151, MType({0xa20000c2666759, 0xc000009000009000})},
        {Sign::POS, -151, MType({0xab6966cb9915d3e1, 0xc800009c4000a2c2})},
        {Sign::POS, -151, MType({0x563477567767f078, 0xd00000a90000b715})},
        {Sign::POS, -151, MType({0x1037e215e50ad20, 0xd80000b64000cd08})},
        {Sign::POS, -151, MType({0xabd6caac4ed779dc, 0xe00000c40000e4aa})},
        {Sign::POS, -151, MType({0x56aeaf774a1806b0, 0xe80000d24000fe0d})},
        {Sign::POS, -151, MType({0x18b82025143039f, 0xf00000e100011940})},
        {Sign::POS, -151, MType({0xac6d9acd659ee0ad, 0xf80000f040013652})},
        {Sign::POS, -150, MType({0xabaaaaac444446ef, 0x800000800000aaaa})},
        {Sign::POS, -150, MType({0x1218811ddba1d9b, 0x840000882000bb2c})},
        {Sign::POS, -150, MType({0x569b96577ff70c5f, 0x880000908000ccb5})},
        {Sign::POS, -150, MType({0xac1907bd2bcd8b3b, 0x8c0000992000df4e})},
        {Sign::POS, -150, MType({0x19a1002e21cd235, 0x900000a20000f300})},
        {Sign::POS, -150, MType({0x571ee468a3d1394e, 0x940000ab200107d1})},
        {Sign::POS, -150, MType({0xaca7bbae71e4988b, 0x980000b480011dca})},
        {Sign::POS, -150, MType({0x234ce144d5ea7f0, 0x9c0000be200134f4})},
        {Sign::POS, -150, MType({0x57c6555a37555f82, 0xa00000c800014d55})},
        {Sign::POS, -150, MType({0xad5c8cc030ed5744, 0xa40000d2200166f6})},
        {Sign::POS, -150, MType({0x2f7b1063b5a273b, 0xa80000dc800181e0})},
        {Sign::POS, -150, MType({0x5898006c57dec76f, 0xac0000e720019e19})},
        {Sign::POS, -150, MType({0xae3dbab287cdefe3, 0xb00000f20001bbaa})},
        {Sign::POS, -150, MType({0x3e92118cc8a789f, 0xb40000fd2001da9c})},
        {Sign::POS, -150, MType({0x599a765f2787b9aa, 0xb80001088001faf5})},
        {Sign::POS, -150, MType({0xaf51fec59a49eb0a, 0xbc00011420021cbe})},
        {Sign::POS, -150, MType({0x510000c266684c6, 0xc000012000024000})},
        {Sign::POS, -150, MType({0x5ad4c172cd849ee9, 0xc400012c200264c1})},
        {Sign::POS, -150, MType({0xb0a08bb9915d5179, 0xc800013880028b0a})},
        {Sign::POS, -150, MType({0x673a92073bc1480, 0xcc0001452002b2e4})},
        {Sign::POS, -150, MType({0x5c4e6567767f2009, 0xd00001520002dc55})},
        {Sign::POS, -150, MType({0xb2310dce9b97cc1d, 0xd400015f20030766})},
        {Sign::POS, -150, MType({0x81bf115e50af0c7, 0xd800016c80033420})},
        {Sign::POS, -150, MType({0x5e0f5f7d54f14614, 0xdc00017a20036289})},
        {Sign::POS, -150, MType({0xb40baac4ed77c410, 0xe0000188000392aa})},
        {Sign::POS, -150, MType({0xa11262cb0e002c7, 0xe40001962003c48c})},
        {Sign::POS, -150, MType({0x60202674a1809a47, 0xe80001a48003f835})},
        {Sign::POS, -150, MType({0xb63901dcc1c582a0, 0xec0001b320042dae})},
        {Sign::POS, -150, MType({0xc5c1025143073df, 0xf00001c200046500})},
        {Sign::POS, -150, MType({0x6289aa8d9b594616, 0xf40001d120049e31})},
        {Sign::POS, -150, MType({0xb8c22bd659ee5155, 0xf80001e08004d94a})},
        {Sign::POS, -150, MType({0xf05f03f52b4cdae, 0xfc0001f020051654})},
        {Sign::POS, -149, MType({0xb2aaaac44444999a, 0x800001000002aaaa})},

    }};
// > P = fpminimax((log(1 + x) - x)/x^2, 2, [|1, 128...|],
//                 [-0x1.0002143p-29 , 0x1p-29]);
// > P;
// > dirtyinfnorm(log(1 + x)/x - x*P, [-0x1.0002143p-29 , 0x1p-29]);
// 0x1.99a3...p-121
const Float128 BIG_COEFFS[3]{
    {Sign::NEG, -129, MType({0xb59c58e5554d581c, 0x800000000006a710})},
    {Sign::POS, -129, MType({0xde05c7c94ae9cbae, 0xaaaaaaaaaaaaaabd})},
    {Sign::NEG, -128, MType({0x0, 0x8000000000000000})},
};

// Reuse the output of the fast pass range reduction.
// -2^-8 <= m_x < 2^-7
double log_accurate(int e_x, int index, double m_x) {

  Float128 e_x_f128(static_cast<float>(e_x));
  Float128 sum = fputil::quick_mul(LOG_2, e_x_f128);
  sum = fputil::quick_add(sum, LOG_TABLE.step_1[index]);

  Float128 v_f128 = log_range_reduction(m_x, LOG_TABLE, sum);
  sum = fputil::quick_add(sum, v_f128);

  // Polynomial approximation
  Float128 p = fputil::quick_mul(v_f128, BIG_COEFFS[0]);
  p = fputil::quick_mul(v_f128, fputil::quick_add(p, BIG_COEFFS[1]));
  p = fputil::quick_mul(v_f128, fputil::quick_add(p, BIG_COEFFS[2]));
  p = fputil::quick_mul(v_f128, p);

  Float128 r = fputil::quick_add(sum, p);

  return static_cast<double>(r);
}

} // namespace

LLVM_LIBC_FUNCTION(double, log, (double x)) {
  using FPBits_t = typename fputil::FPBits<double>;
  using Sign = fputil::Sign;
  FPBits_t xbits(x);
  uint64_t x_u = xbits.uintval();

  int x_e = -FPBits_t::EXP_BIAS;

  if (LIBC_UNLIKELY(xbits == FPBits_t::one())) {
    // log(1.0) = +0.0
    return 0.0;
  }

  if (LIBC_UNLIKELY(xbits.uintval() < FPBits_t::min_normal().uintval() ||
                    xbits.uintval() > FPBits_t::max_normal().uintval())) {
    if (xbits.is_zero()) {
      // return -Inf and raise FE_DIVBYZERO.
      fputil::set_errno_if_required(ERANGE);
      fputil::raise_except_if_required(FE_DIVBYZERO);
      return FPBits_t::inf(Sign::NEG).get_val();
    }
    if (xbits.is_neg() && !xbits.is_nan()) {
      fputil::set_errno_if_required(EDOM);
      fputil::raise_except_if_required(FE_INVALID);
      return FPBits_t::build_quiet_nan().get_val();
    }
    if (xbits.is_inf_or_nan()) {
      return x;
    }
    // Normalize denormal inputs.
    xbits = FPBits_t(x * 0x1.0p52);
    x_e -= 52;
    x_u = xbits.uintval();
  }

  // log(x) = log(2^x_e * x_m)
  //        = x_e * log(2) + log(x_m)

  // Range reduction for log(x_m):
  // For each x_m, we would like to find r such that:
  //   -2^-8 <= r * x_m - 1 < 2^-7
  int shifted = static_cast<int>(x_u >> 45);
  int index = shifted & 0x7F;
  double r = RD[index];

  // Add unbiased exponent. Add an extra 1 if the 8 leading fractional bits are
  // all 1's.
  x_e += static_cast<int>((x_u + (1ULL << 45)) >> 52);
  double e_x = static_cast<double>(x_e);

  // hi is exact
  double hi = fputil::multiply_add(e_x, LOG_2_HI, LOG_R_DD[index].hi);
  // lo errors ~ e_x * LSB(LOG_2_LO) + LSB(LOG_R[index].lo) + rounding err
  //           <= 2 * (e_x * LSB(LOG_2_LO) + LSB(LOG_R[index].lo))
  double lo = fputil::multiply_add(e_x, LOG_2_LO, LOG_R_DD[index].lo);

  // Set m = 1.mantissa.
  uint64_t x_m = (x_u & 0x000F'FFFF'FFFF'FFFFULL) | 0x3FF0'0000'0000'0000ULL;
  double m = FPBits_t(x_m).get_val();

  double u, u_sq, err;
  fputil::DoubleDouble r1;

  // Perform exact range reduction
#ifdef LIBC_TARGET_CPU_HAS_FMA
  u = fputil::multiply_add(r, m, -1.0); // exact
#else
  uint64_t c_m = x_m & 0x3FFF'E000'0000'0000ULL;
  double c = FPBits_t(c_m).get_val();
  u = fputil::multiply_add(r, m - c, CD[index]); // exact
#endif // LIBC_TARGET_CPU_HAS_FMA

  // Exact sum:
  //   r1.hi + r1.lo = e_x * log(2)_hi - log(r)_hi + u
  r1 = fputil::exact_add(hi, u);

  // Error of u_sq = ulp(u^2);
  u_sq = u * u;
  // Total error is bounded by ~ C * ulp(u^2).
  // Degree-7 minimax polynomial
  double p0 = fputil::multiply_add(u, LOG_COEFFS[1], LOG_COEFFS[0]);
  double p1 = fputil::multiply_add(u, LOG_COEFFS[3], LOG_COEFFS[2]);
  double p2 = fputil::multiply_add(u, LOG_COEFFS[5], LOG_COEFFS[4]);
  double p = fputil::polyeval(u_sq, lo + r1.lo, p0, p1, p2);

  // Technicallly error of r1.lo is bounded by:
  //    hi*ulp(log(2)_lo) + C*ulp(u^2)
  // To simplify the error computation a bit, we replace |hi|*ulp(log(2)_lo)
  // with the upper bound: 2^11 * ulp(log(2)_lo) = 2^-85.
  // Total error is bounded by ~ C * ulp(u^2) + 2^-85.
  err = fputil::multiply_add(u_sq, P_ERR, HI_ERR);

  // Lower bound from the result
  double left = r1.hi + (p - err);
  // Upper bound from the result
  double right = r1.hi + (p + err);

  // Ziv's test if fast pass is accurate enough.
  if (left == right)
    return left;

  return log_accurate(x_e, index, u);
}

} // namespace LIBC_NAMESPACE
